﻿using Infrastructure;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Drawing;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Documents;
using SuperSimpleTcp;
using GetClient_info;
using System.Threading;

namespace Vision.AlgBase
{
    /// <summary>
    /// 添加指令模块基类
    /// </summary>
    [Serializable]
    public abstract class ToolBase : OperationWindowProcess, IAlg
    {
        #region 公有属性

        public string Name
        {
            get { return name; }
            set { name = value; OnPropertyChanged(); }
        }
        private string name = string.Empty;

        [field: NonSerialized, Browsable(false)]
        public RunStatus ToolRunStatus
        {
            get { return toolRunStatus; }
            set { toolRunStatus = value; OnPropertyChanged(); }
        }
        [NonSerialized]
        private RunStatus toolRunStatus = RunStatus.UnStart;

        /// <summary>
        /// 是否使能/执行
        /// </summary>
        public virtual bool IsEnable
        {
            get { return isEnable; }
            set { isEnable = value; OnPropertyChanged(); }
        }
        private bool isEnable = true;

        [field: NonSerialized]
        public long RunTime
        {
            get { return runTime; }
            private set { runTime = value; OnPropertyChanged(); }
        }
        [NonSerialized]
        private long runTime = 0;

        /// <summary>
        /// TCP客户端
        /// </summary>
        public static SimpleTcpClient Client
        {
            get { return _client; }
            set { _client = value; }
        }
        private static SimpleTcpClient _client = null;

        /// <summary>
        /// 外部测试exe名称
        /// </summary>
        public  string TestAppName
        {
            get { return _testAppName; }
            set { _testAppName = value; }
        }
        private  string _testAppName = "WinFormCurrentTest";
        /// <summary>
        /// 控件在桌面中的坐标
        /// </summary>
        public  Point ControlPoint
        {
            get { return _controlPoint; }
            set { _controlPoint = value; }
        }
        private  Point _controlPoint = new Point(1760,80);
        /// <summary>
        /// 外部程序的句柄
        /// </summary>
        public static IntPtr WindowIntprt
        {
            get { return _windowIntprt; }
            set { _windowIntprt = value; }
        }
        static IntPtr _windowIntprt = IntPtr.Zero;
        /// <summary>
        /// 控件的句柄
        /// </summary>
        public static IntPtr ContorIntprt
        {
            get { return _contorIntprt; }
            set { _contorIntprt = value; }
        }
        static IntPtr _contorIntprt = IntPtr.Zero;
        /// <summary>
        /// 识别到的控件文本
        /// </summary>
        public  string ResultText
        {
            get { return _resultText; }
            set { _resultText = value; OnPropertyChanged(); }
        }
         string _resultText = string.Empty;
 
        /// <summary>
        /// 运行出错信息
        /// </summary>
        public  string ErrLog
        {
            get { return _errLog; }
            set { _errLog = value; OnPropertyChanged(); }
        }
         string _errLog = string.Empty;

        #endregion 公有属性

        #region 公有函数
        /// <summary>
        /// 指令执行函数
        /// </summary>
        /// <param name="InputsDic"></param>
        /// <param name="OutputsDic"></param>
        /// <returns></returns>
        public virtual bool Run()
        {
            if (!IsEnable) return true;
            OnRunning();
            bool bret = false;
            try
            {
                bret = Excute();
            }
            catch (Exception ex)
            {
                MessageData data = new MessageData(MessageType.Error, ex.ToString());
                GlobalLogMessageEvent.Publish(data);
                LogServiceHelper.Error(ex.ToString());
            }
            RunStatus status = bret ? RunStatus.Success : RunStatus.Fail;
            OnRan(status);
            return bret;
        }

        protected abstract bool Excute();

        /// <summary>
        /// 触发执行完成事件
        /// </summary>
        protected virtual void OnRan(RunStatus status)
        {
            RunSt.Stop();
            MessageType type = MessageType.Info;
            string msg = $"执行{Name}成功 ({RunSt.ElapsedMilliseconds} ms)";
            RunTime = RunSt.ElapsedMilliseconds;
            ToolRunStatus = status;
            if (status == RunStatus.Fail)
            {
                type = MessageType.Error;
                msg = $"执行{Name}失败 ({RunSt.ElapsedMilliseconds} ms)";
            }

            MessageData data = new MessageData(type, msg);
            GlobalLogMessageEvent.Publish(data);
        }

        /// <summary>
        /// 触发开始执行函数
        /// </summary>
        protected virtual void OnRunning()
        {
            ToolRunStatus = RunStatus.Running;
            if (RunSt == null) RunSt = new Stopwatch();
            RunSt.Restart();
        }



        #region INotifyPropertyChanged
        [field: NonSerialized]
        public event PropertyChangedEventHandler PropertyChanged;


        protected void OnPropertyChanged([CallerMemberName] string propertyName = null)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
            }
        }
        #endregion INotifyPropertyChanged

        object ICloneable.Clone()
        {
            return Clone();
        }

        public virtual IAlg Clone()
        {
            Type type = GetType();
            IAlg tool = (IAlg)Activator.CreateInstance(type);
            PropertyInfo[] properties = GetType().GetProperties();
            foreach (var item in properties)
            {
                if (item.CanRead && item.CanWrite)
                {
                    object value = item.GetValue(this);
                    if (!item.PropertyType.IsValueType)
                    {
                        if (value is ICloneable && null != value)
                        {
                            value = (value as ICloneable).Clone();
                        }
                    }
                    item.SetValue(tool, value);
                }
            }
            return tool;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="tarType"></param>
        /// <param name="souType"></param>
        /// <returns></returns>
        internal static bool IsTypeCanSet(Type tarType, Type souType)
        {
            if (null == tarType || souType == null) return false;
            if (tarType == typeof(object) || souType == typeof(object) || souType == tarType) return true;
            return tarType.IsAssignableFrom(souType);
        }
        /// <summary>
        /// 置顶窗口，并根据坐标获取控件句柄
        /// </summary>
        /// <param name="point"></param>
        /// <returns></returns>
        public  string GetIntPtr()
        {
            if (IsFirst(_testAppName))
            {
                //获取窗体的句柄
                _windowIntprt = OperationWindowProcess.GetIntPtrFromStr(_testAppName);
                //置顶窗体
                OperationWindowProcess.WindowMaxAndTop(_windowIntprt);
                Thread.Sleep(200);
                _contorIntprt = OperationWindowProcess.WindowFromPoint(_controlPoint);
                if (_contorIntprt == IntPtr.Zero)
                {
                    return "获取控件坐标错误，请确认坐标是否正常";
                }
                else
                    return "OK";
            }
            else
                return "外部测试程序未运行";


        }





        #endregion 公有函数

        [NonSerialized]
        protected Stopwatch RunSt = new Stopwatch();
    }
}
